// Promise
type DeepPromiseValueType<P extends Promise<unknown>> = P extends Promise<
  infer ValueType
>
  ? ValueType extends Promise<unknown>
    ? DeepPromiseValueType<ValueType>
    : ValueType
  : never;
type ttt = Promise<Promise<Promise<Record<string, any>>>>;
type Test1 = DeepPromiseValueType<ttt>;

// 数组
type ReverseArr<Arr extends unknown[]> = Arr extends [
  infer First,
  ...infer Rest
]
  ? [...ReverseArr<Rest>, First]
  : Arr;
type Test2 = ReverseArr<[1, 2, 3, 4, 5]>;

type IsEqual<A, B> = (A extends B ? true : false) & (B extends A ? true : false);
type Includes<Arr extends unknown[], FindItem> = Arr extends [
  infer Frist,
  ...infer Rest
]
  ? IsEqual<Frist, FindItem> extends true
    ? true
    : Includes<Rest, FindItem>
  : false;
type Test3 = Includes<[1,2,3,4,5], 5>

type RemoveItem<Arr extends unknown[], Item, Result extends unknown[] = []> = Arr extends 
    [infer Frist, ...infer Rest] ? IsEqual<Item, Frist> extends true ? 
    RemoveItem<Rest, Item, Result> : RemoveItem<Rest, Item, [...Result, Frist]> : Result
type Test4 = RemoveItem<[1,2,3,4,3,3,3,5], 3>


type BuildArray<Length = number, Ele =unknown, Arr extends unknown[] = []> = Arr['length'] extends Length ? 
    Arr : BuildArray<Length, Ele, [...Arr, Ele]>

type Test5= BuildArray<5, number>

// 字符串

type ReplaceAll<Str extends string, From extends string, To extends string> = Str extends `${infer Left}${From}${infer Right}` ?
    `${Left}${To}${ReplaceAll<Right, From, To>}` : Str

type Test6= ReplaceAll<'abcabcabc', 'c', 'd'>

type StringToUnion<Str extends string> = Str extends `${infer Frist}${infer Rest}` ?  StringToUnion<Rest> | Frist : never

type Test7 = StringToUnion<'abcd'>

type ReverseStr<Str extends string> = Str extends `${infer Frist}${infer Rest}` ? `${ReverseStr<Rest>}${Frist}` : Str
type Test8 = ReverseStr<'hello'>

// 对象

type DeepReadonly<Obj extends Record<string, any>> = Obj extends any ? {
    readonly [Key in keyof Obj]: Obj[Key] extends object ? Obj[Key] extends Function ? Obj[Key] : DeepReadonly<Obj[Key]> : Obj[Key]
}: never

type obj = {
    a: {
        b: {
            c: {
                f: () => 'dong',
                d: {
                    e: {
                        guang: string
                    }
                }
            }
        }
    }
}

type Test9= DeepReadonly<obj>